/** * The MIT License * ------------------------------------------------------------- * Copyright (c) 2008, Rob Ellis, Brock Whitten, Brian Leroux, Joe Bowser, Dave Johnson, Nitobi * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package com.phonegap.api.impl; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import javax.microedition.io.Connector; import javax.microedition.io.file.FileConnection; import net.rim.blackberry.api.invoke.CameraArguments; import net.rim.blackberry.api.invoke.Invoke; import net.rim.device.api.io.Base64OutputStream; import net.rim.device.api.io.file.FileSystemJournal; import net.rim.device.api.io.file.FileSystemJournalEntry; import net.rim.device.api.io.file.FileSystemJournalListener; import net.rim.device.api.system.Characters; import net.rim.device.api.system.ControlledAccessException; import net.rim.device.api.system.EventInjector; import net.rim.device.api.ui.UiApplication; import com.phonegap.PhoneGap; import com.phonegap.api.Command; /** * Switches current application to the camera to take a photo. * * @author Jose Noheda * */ public class CameraCommand implements Command { private static final int PICTURE_COMMAND = 0; private static final String CODE = "PhoneGap=camera"; private static final String CAMERA_ERROR_CALLBACK = ";if (navigator.camera.onError) { navigator.camera.onError(); }"; private long lastUSN = 0; private String photoPath; private String returnVal; private FileSystemJournalListener listener; private PhoneGap berryGap; public CameraCommand(PhoneGap phoneGap) { berryGap = phoneGap; listener = new FileSystemJournalListener() { public void fileJournalChanged() { long USN = FileSystemJournal.getNextUSN(); for (long i = USN - 1; i >= lastUSN; --i) { FileSystemJournalEntry entry = FileSystemJournal.getEntry(i); if (entry != null) { if (entry.getEvent() == FileSystemJournalEntry.FILE_CHANGED) { if (entry.getPath().indexOf(".jpg") != -1) { lastUSN = USN; photoPath = entry.getPath(); InputStream theImage; byte[] imageBytes; Base64OutputStream base64OutputStream = null; try { FileConnection fconn = (FileConnection)Connector.open("file://" + photoPath); imageBytes = new byte[(int) fconn.fileSize()]; theImage = fconn.openInputStream(); theImage.read(imageBytes); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream( imageBytes.length ); base64OutputStream = new Base64OutputStream( byteArrayOutputStream ); base64OutputStream.write(imageBytes); base64OutputStream.flush(); base64OutputStream.close(); byteArrayOutputStream.flush(); byteArrayOutputStream.close(); //int sizeofbase64 = byteArrayOutputStream.toString().length(); returnVal = ";if (navigator.camera.onSuccess) { navigator.camera.onSuccess('"+byteArrayOutputStream.toString()+"'); }"; } catch (IOException e) { e.printStackTrace(); returnVal = CAMERA_ERROR_CALLBACK; } berryGap.pendingResponses.addElement(returnVal); closeCamera(); } } } } lastUSN = USN; } }; } /** * Determines whether the specified instruction is accepted by the command. * @param instruction The string instruction passed from JavaScript via cookie. * @return true if the Command accepts the instruction, false otherwise. */ public boolean accept(String instruction) { return instruction != null && instruction.startsWith(CODE); } /** * Invokes internal camera application. */ public String execute(String instruction) { switch (getCommand(instruction)) { case PICTURE_COMMAND: photoPath = null; returnVal = null; UiApplication.getUiApplication().addFileSystemJournalListener(listener); Invoke.invokeApplication(Invoke.APP_TYPE_CAMERA, new CameraArguments()); return ""; } return null; } private int getCommand(String instruction) { String command = instruction.substring(instruction.lastIndexOf('/') + 1); if ("picture".equals(command)) return PICTURE_COMMAND; return -1; } public void closeCamera() { try { UiApplication.getUiApplication().removeFileSystemJournalListener(listener); EventInjector.KeyEvent inject = new EventInjector.KeyEvent(EventInjector.KeyEvent.KEY_DOWN, Characters.ESCAPE, 0); inject.post(); inject.post(); } catch (ControlledAccessException ex) { // Don't allow key injection - figure out what to do } } }